package com.liuceng.zen.service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.Errors;

import com.liuceng.zen.common.Result;
import com.liuceng.zen.common.utils.Encodes;
import com.liuceng.zen.mapper.MemberMapper;
import com.liuceng.zen.pojo.domain.Member;
import com.liuceng.zen.pojo.form.ModifyPasswordForm;
import com.liuceng.zen.pojo.form.ProfileForm;
import com.liuceng.zen.web.auth.realm.ShiroDbRealm.UserContext;
import com.liuceng.zen.web.auth.utils.AuthUtils;

@Service
public class MemberService extends BaseService<Member> {
  @Autowired
  private MemberMapper memberMapper;
  @Value("${autologin.referer}")
  private String referer;

  /**
   * @param username
   * @return
   */
  public Member selectByuserName(String username) {
    Member member = memberMapper.selectByuserName(username);
    return member;
  }

  /**
   * @param member
   */
  @Transactional
  public void insertSelecttive(Member member) {
    memberMapper.insertSelective(member);
  }

  /**
   * @param newPassword
   * @param currentUser
   */
  @Transactional
  public void updatePassword(String newPassword, UserContext currentUser) {
    String[] saltAndPassword = AuthUtils.generateSaltAndPassword(newPassword);
    Member member = currentUser.getMember();
    member.setPassword(saltAndPassword[1]);
    member.setSalt(saltAndPassword[0]);
    memberMapper.updateByPrimaryKeySelective(member);
  }

  /**
   * @param form
   * @return
   */
  @Transactional
  public Result updateAcManage(ProfileForm form) {
    Result result = new Result();
    Errors errors = new BeanPropertyBindingResult(new ProfileForm(), "form");

    Map<String, Object> params = new HashMap<String, Object>();
    params.put("id", form.getCurrentUserId());
    Member members = memberMapper.findMember(params);

    members.setQq(form.getQq());
    members.setMobile(form.getMobile());
    members.setAvatarId(form.getAvatarId());

    // email唯一不能重复
    if (emailExists(form.getCurrentUserId(), form.getEmail())) {
      result.setErrors(errors);
      return result;
    }
    members.setEmail(form.getEmail());

    // companyName唯一不能重复
    if (companyNameExists(form.getCurrentUserId(), form.getCompanyName())) {
      result.setErrors(errors);
      return result;
    }
    members.setCompanyName(form.getCompanyName());

    members.setPhone(form.getPhone());
    members.setAddress(form.getAddress());
    members.setUpdatedAt(new Date());
    members.setAvatarPath(form.getPicPath());
    memberMapper.updateByPrimaryKeySelective(members);

    return result;
  }

  public Member selectByEmail(String email) {
    return memberMapper.selectByEmail(email);
  }

  @Transactional(readOnly = true)
  public boolean emailExists(Integer id, String email) {
    return memberMapper.countMembersByEmail(id, email) > 0 ? true : false;
  }

  @Transactional(readOnly = true)
  public boolean companyNameExists(Integer id, String companyName) {
    return memberMapper.countMembersByCompanyName(id, companyName) > 0 ? true : false;
  }

  public Member findMember(Integer id) {
    Map<String, Object> params = new HashMap<String, Object>();
    params.put("id", id);
    return memberMapper.findMember(params);
  }

  @Transactional
  public Result updatePassword(ModifyPasswordForm form) {
    Result result = new Result();
    Errors errors = new BeanPropertyBindingResult(new ModifyPasswordForm(), "form");

    Map<String, Object> params = new HashMap<String, Object>();
    params.put("id", form.getCurrentUserId());
    Member member = memberMapper.findMember(params);

    String oldPassword = form.getOldPassword();
    String newPassword = form.getNewPassword();
    String confirmNewPassword = form.getNewPassword2();

    if (!newPassword.equals(confirmNewPassword)) {
      errors.rejectValue("newPassword", "", "新密码两次录入不一致");
      result.setErrors(errors);
      return result;
    }

    if (oldPassword.equals(newPassword)) {
      errors.rejectValue("newPassword2", "", "新旧密码一致，不需要修改");
      result.setErrors(errors);
      return result;
    }

    String hashedPassword =
        AuthUtils.encryptPlainPassword(oldPassword, Encodes.decodeHex(member.getSalt()));

    if (!hashedPassword.equals(member.getPassword())) {
      errors.rejectValue("oldPassword", "", "原密码输入错误");
      result.setErrors(errors);
      return result;
    }

    member.setPassword(
        AuthUtils.encryptPlainPassword(newPassword, Encodes.decodeHex(member.getSalt())));
    update(member);

    return result;
  }

  public String getReferer() {
    return referer;
  }

  public void setReferer(String referer) {
    this.referer = referer;
  }

  public Member selectByWeChat(String unionid,String openid){
    Map<String, Object> params = new HashMap<>();
    params.put("unionid",unionid);
    params.put("openid",openid);
    return memberMapper.selectByWeChat(params);
  }
}
